import datetime 
import webapp2

from framework import BaseHandler
from model import *
import currency

def int_def(x, default=None):
    try: return int(x)
    except ValueError: return default

def update_model(model, values):
    for k, v in values.iteritems():
        setattr(model, k, v)

class MainPage(BaseHandler):
    def get(self):
        # Get last few transactions
        q = Transaction.all().ancestor(self.user_info.key()).order('-created')
        last_trns = list(q.fetch(5))

        # Create form
        edit_mode = False
        form_post_data = self.session.pop('main.add_form_data', None)
        if form_post_data is None:
            transaction_id = int_def(self.request.get('id'))
            transaction = Transaction.get_by_id(transaction_id, parent=self.user_info.key()) if transaction_id else None
            if not transaction: 
                # Add new transaction
                today = datetime.date.today()
                if last_trns and last_trns[0].created.date() == today: date = last_trns[0].date
                else: date = today
                form = TransactionForm(date=date)
            else:
                # Edit transaction
                form = TransactionForm(obj=transaction, id=transaction_id)
                edit_mode = True
        else:
            # Form validation error occurred, show same again 
            form = TransactionForm(form_post_data)
            form.validate()

        accounts = list(Account.all())
        amount_list = [(a.balance(), a.currency) for a in accounts]

        template_values = {
            'last_transactions': last_trns,
            'accounts': accounts,
            'total_balance': dict([(cur, '%.2f'%currency.add(amount_list, cur)) for cur in ['EUR', 'CHF', 'BGN']]),
            'form': form,
            'edit_mode': edit_mode,
        }
        return ('index.html', template_values)


class AddTransaction(BaseHandler):
    def post(self):
        form = TransactionForm(self.request.POST)
        if form.validate():
            # Save the data
            data = form.data
            income = data.pop('income', False)
            sign = 1 if income else -1
            data['amount'] = sign * abs(data['amount'])
            data['to_amount'] = -sign * abs(data['to_amount'])
            transaction_id = int_def(data['id'])
            transaction = Transaction.get_by_id(transaction_id, parent=self.user_info.key()) if transaction_id else None
            if transaction is None:
                transaction = Transaction(parent=self.user_info.key(), **data)
            else:
                update_model(transaction, data)
            transaction.put()
            
            # Update user_info
            #user_info.last_trn_date = data['date']
            #user_info.last_trn_account = data['account']
            #user_info.put()
        else:
            self.session['main.add_form_data'] = self.request.POST 
            
        # Redirect to the previous page (remove params)
        self.redirect(self.request.headers['Referer'].split('?')[0])


class AccountPage(BaseHandler):
    def get(self):
        account_id = int_def(self.request.get('id'))
        account = Account.get_by_id(account_id, parent=self.user_info.key()) if account_id else None
        if not account:
            self.abort(404)
        
        form = AccountForm(obj=account, id=account_id)
        
        template_values = {
            'form': form,
            'transactions': account.external_trns, 
        }
        return ('account.html', template_values)
        

class AccountsPage(BaseHandler):
    def get(self):
        accounts = list(Account.all().ancestor(self.user_info.key()))
        
        # Create form
        edit_mode = False
        form_post_data = self.session.pop('accounts.add_form_data', None)
        if form_post_data is None:
            account_id = int_def(self.request.get('id'))
            account = Account.get_by_id(account_id, parent=self.user_info.key()) if account_id else None
            edit_mode = account is not None
            if not edit_mode: # Add new account
                form = AccountForm()
            else: # Edit account
                form = AccountForm(obj=account, id=account_id)
        else:
            # Form validation error occurred, show same again 
            form = AccountForm(form_post_data)
            form.validate()
            
        template_values = {
            'accounts': accounts,
            'form': form,
            'edit_mode': edit_mode,
        }
        return ('accounts.html', template_values)
    
    def post(self):
        form = AccountForm(self.request.POST)
        if form.validate():
            data = form.data
            data['name'] = data['name'].lower()
            account_id = int_def(data['id'])
            account = Account.get_by_id(account_id, parent=self.user_info.key()) if account_id else None
            if account is None:
                account = Account(parent=self.user_info.key(), **data)
            else:
                update_model(account, data)
            account.put()
        else:
            self.session['accounts.add_form_data'] = self.request.POST
        # Redirect to the previous page (remove params)
        self.redirect(self.request.headers['Referer'].split('?')[0])


class AllTransactionsPage(BaseHandler):
    def get(self):
        q = Transaction.all().ancestor(self.user_info.key()).order("-created").order("-date")
        transactions = list(q)

        template_values = {
            'transactions': transactions,
        }
        return ('all.html', template_values)
            

url_mapping = [('/', MainPage),
               ('/add', AddTransaction),
               ('/accounts', AccountsPage),
               ('/account', AccountPage),
               ('/all', AllTransactionsPage),
               ]

config = {}
config['webapp2_extras.sessions'] = {
    'secret_key': 'o3$74FryDms,hq-3t4D8fnqmdq',
}
app = webapp2.WSGIApplication(url_mapping, debug=True, config=config)
